package com.xzavier.yunlian_interview.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xzavier.yunlian_interview.entity.ClockRes;
import com.xzavier.yunlian_interview.entity.User;
import com.xzavier.yunlian_interview.mapper.ClockResMapper;
import com.xzavier.yunlian_interview.mapper.UserMapper;
import com.xzavier.yunlian_interview.service.ClockResService;
import com.xzavier.yunlian_interview.service.ex.ClockResException;
import com.xzavier.yunlian_interview.view.ClockInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Time;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class ClockResServiceImpl implements ClockResService {
    @Autowired
    ClockResMapper clockResMapper;
    @Autowired
    UserMapper userMapper;


    @Override
    public User dailyClock(String userId) {
        if (userId == null || userId.isEmpty()) {
            throw new ClockResException("userId is null or empty");
        }

        // 查询用户
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("id", userId);
        User user = userMapper.selectOne(userQueryWrapper);
        if (user == null) {
            throw new ClockResException("用户不存在");
        }

        // 获取当前日期和时间
        Date currentDate = new Date();
        Time currentTime = new Time(System.currentTimeMillis());

        // 创建打卡记录
        ClockRes clockRes = new ClockRes();
        clockRes.setUserId(userId);
        clockRes.setCheckinDate(currentDate);
        clockRes.setCheckinTime(currentTime);
        clockRes.setStatus(1);

        // 查询今天是否有打卡记录
        QueryWrapper<ClockRes> clockResQueryWrapper = new QueryWrapper<>();
        clockResQueryWrapper.eq("userId", userId);
        clockResQueryWrapper.orderByDesc("checkinDate");
        List<ClockRes> clockRes1 = clockResMapper.selectList(clockResQueryWrapper);
        ClockRes existingClockRes;
        if (clockRes1 == null || clockRes1.isEmpty()) {
            existingClockRes = null;

        } else {
            existingClockRes = clockRes1.getFirst();
        }
        //todo:相差不超过一天
        if (existingClockRes != null && isWithinOneDay(new Date(), existingClockRes.getCheckinDate())) {
            throw new ClockResException("已打卡");
        }

        // 插入新的打卡记录
        clockResMapper.insert(clockRes);

        // 更新用户的打卡次数
        user.setClockinNumbers(user.getClockinNumbers() + 1);
        userMapper.updateById(user);

        return user;
    }

    @Override
    public ClockInfo dailyClockInfo(String userId, Integer year, Integer month) {
        if (userId == null || userId.isEmpty()) {
            throw new ClockResException("userId is null or empty");
        }
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("id", userId);
        User user = userMapper.selectOne(userQueryWrapper);
        if (user == null) {
            throw new ClockResException("用户不存在");
        }
        QueryWrapper<ClockRes> clockInfoQueryWrapper = new QueryWrapper<>();
        clockInfoQueryWrapper.eq("userId", userId);

        if (year != null && month != null) {
            // 过滤指定年份和月份的记录
            clockInfoQueryWrapper.between("checkinDate", LocalDate.of(year, month, 1), LocalDate.of(year, month, 1).plusMonths(1));
        }

        clockInfoQueryWrapper.orderByDesc("checkinDate")
                .orderByDesc("checkinTime");
        List<ClockRes> clockRes = clockResMapper.selectList(clockInfoQueryWrapper);
        if (!clockRes.isEmpty() && !isWithinOneDay(new Date(), clockRes.getFirst().getCheckinDate())) {
            this.dailyClock(userId);
        }
        ClockInfo clockInfo = new ClockInfo();
        clockInfo.setTotalClockinNumber((!clockRes.isEmpty()) ? clockRes.size() : 0);
        clockInfo.setFlag(!clockRes.isEmpty() && clockRes.getFirst().getStatus() == 1);

        if (clockRes.isEmpty()) {
            clockInfo.setClockinNumbers(0);
            clockInfo.setClockins(new ArrayList<>());
            return clockInfo;
        }

        int sum = 1;
        for (int i = 0; i < clockRes.size() - 1; i++) {
            if (isWithinOneDay(clockRes.get(i).getCheckinDate(), clockRes.get(i + 1).getCheckinDate())) {
                sum += 1;
            } else {
                break;
            }
        }
        clockInfo.setClockinNumbers(sum);
        clockInfo.setClockins(clockRes);
        return clockInfo;
    }


    public static boolean isWithinOneDay(Date date1, Date date2) {
        LocalDate localDate1 = date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate localDate2 = date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

        return Math.abs(localDate1.toEpochDay() - localDate2.toEpochDay()) < 1;
    }

}
